package com.acme.ionio.impl;

import com.acme.ionio.FileCopierServer;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

/**
 * @author Gregory Sobko
 */
public class FileCopierServerNIO implements FileCopierServer {
    private static Logger logger = Logger.getLogger(FileCopierServerNIO.class);

    @Override
    public void copy(File to, int port) throws IOException {
        logger.info("Waiting for user connection...");

        try(ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            FileChannel foc = new FileOutputStream(to).getChannel()){
            CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
            serverSocketChannel.configureBlocking(true);
            serverSocketChannel.socket().bind(new InetSocketAddress(FileCopierServer.DEFAULT_PORT));
            SocketChannel socketChannel = serverSocketChannel.accept();
            logger.info("User connected!");
            ByteBuffer byteBuffer = ByteBuffer.allocate(8);
            logger.debug("Reading filesize...");
            socketChannel.read(byteBuffer);
            logger.debug("Received filesize");
            long length = 0;
            try{
                byteBuffer.rewind();
                length = byteBuffer.asLongBuffer().get(0);
            }catch (Exception e){
                e.printStackTrace();
            }
            foc.transferFrom(socketChannel, 0, length);

            socketChannel.write(encoder.encode(CharBuffer.wrap("File was written successfully\n")));

            logger.info("Server done!");
            serverSocketChannel.socket().close();
        }
    }

    @Override
    public void copy(File to) throws IOException {
        copy(to, DEFAULT_PORT);
    }
}
